package com.fancy.projecty.O组任务;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 组任务
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class A_组任务 {

	@Test
	public void c_李四完成自己的任务() {
		//李四完成了自己的任务(完成任务之前需要先判断是否有这个任务.)
		// 下面的taskid是从taskid里面查询出来的.
		this.taskService.complete("112502");

	}


	@Test
	public void c_李四查询自己的任务() {
		List<Task> list = this.taskService.createTaskQuery()
				.processDefinitionKey("holiday5").taskAssignee("lisi")
				.list();

		for (Task task : list) {
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getId());
			System.out.println(task.getName());
			System.out.println(task.getAssignee());//获取任务的执行人,这里再打印assignee就有值了,因为已经拾取了任务
		}


	}


	/**
	 * 任务交接，前提要保证当前用户是这个任务的负责人，这时候他才可以有权限去将任务交接给其他候选人
	 */
	@Test
	public void c_张三给任务交接给李四() {
		Task task = this.taskService
				.createTaskQuery()
				.processDefinitionKey("holiday5")
				.taskAssignee("zhangsan") //设置任务的负责人
				.singleResult();        //5.判断是否有这个任务
		if (task != null) {
			//交接任务为lisi  ,交接任务就是一个候选人拾取用户的过程
			taskService.setAssignee(task.getId(), "lisi");
			System.err.println("任务交接完成");
		} else {

			System.err.println("张三没有任务");
		}

	}


	@Test
	public void c_张三完成自己的任务() {
		Task task = this.taskService.createTaskQuery().processDefinitionKey("holiday5")
				.taskAssignee("zhangsan")
				.singleResult();
		if (task != null) {
			this.taskService.complete(task.getId());
			System.err.println("张三任务已经完成了");

		} else {
			System.err.println("张三没有任务");
		}


	}


	@Test
	public void c_张三查询自己的任务() {
		List<Task> list = this.taskService.createTaskQuery()
				.processDefinitionKey("holiday5")
				.taskAssignee("zhangsan")
				.list();

		for (Task task : list) {
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getId());
			System.out.println(task.getName());
			System.out.println(task.getAssignee());//获取任务的执行人,这里再打印assignee就有值了,因为已经拾取了任务
		}
	}


	/**
	 * 测试zhangsan用户，来拾取组任务
	 * 抽取任务的过程就是将候选用户转化为真正任务的负责人（让任务的assignee有值）
	 */
	@Test
	public void c_张三拾取用户() {
		Task task = this.taskService
				.createTaskQuery()//返回一个新的动态查询任务
				.processDefinitionKey("holiday5")  //仅选择具有给定流程定义键的流程实例一部分的任务
				.taskCandidateUser("zhangsan") //设置候选用户
				.singleResult();
		if (task != null) { // 如果不为空,就代码当前有组任务
			/**
			 * 参数1 : 任务ID
			 * 参数2: 具体的候选用户名
			 * 注意,只是拾取了,但是任务依然还是需要审核的这一环节
			 */
			taskService.claim(task.getId(), "zhangsan");
			System.out.println("张三任务拾取完毕!");
		} else {
			System.err.println("张三没有这个任务");
		}
	}


	@Test
	public void c_查询候选用户的组任务() {

		List<Task> zhangsan = this.taskService
				.createTaskQuery()//返回一个新的动态查询任务
				.taskCandidateUser("zhangsan")  //设置候选用户
				.list();
		for (Task task : zhangsan) {
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getId());
			System.out.println(task.getName());
			System.out.println(task.getAssignee());//这里assignee为null，说明当前的zhangsan只是一个候选人，并不是任务的执行人
		}
	}


	@Test
	public void c_小张开始查询自己的任务() {
		Task task = this.taskService.createTaskQuery()
				.processDefinitionKey("holiday5")
				.taskAssignee("xiaozhang")
				.singleResult();
		if (task != null) {
			taskService.complete(task.getId());
			System.err.println("用户任务执行完毕...");
		} else {
			System.err.println("用户没有这个任务.....");
		}

	}


	@Test
	public void c_启动流程实例() {

		ProcessInstance holiday5 = this.runtimeService.startProcessInstanceByKey("holiday5");
		//下面打印的是流程实例的内容
		//流程部署ID
		String deploymentId = holiday5.getDeploymentId();
		System.out.println("deploymentId = " + deploymentId); //null
		//流程定义id
		String processDefinitionId = holiday5.getProcessDefinitionId();
		System.out.println("processDefinitionId = " + processDefinitionId);  //processDefinitionId = holiday:2:2504
		//流程实例id ,是自己的唯一id号
		String id = holiday5.getId();
		System.out.println("id = " + id);  //id = 5001
		//活动id 当前正在执行的某一节点是什么
		String activityId = holiday5.getActivityId();
		System.out.println("activityId = " + activityId); // null

	}


	@Test
	public void c_部署流程() {
		//得到repositoryService 就可以操作部署相关的操作了.
		//1. 添加资源, png资源可以不添加,但是bpmn资源是必须要添加的
		Deployment deployment = this.repositoryService.createDeployment()
				.addClasspathResource("diagram/holiday5.bpmn")
//				.addClasspathResource("diagram/holiday.png")
				//给流程添加名字
				.name("请假申请单流程")
				//开始部署
				.deploy();
		System.out.println(deployment.getName());
		System.out.println(deployment.getId());

	}


	/*历史记录的查询*/
	@Autowired
	private HistoryService historyService;

	@Autowired
	/*管理流程定义,部署相关的Service*/
	private RepositoryService repositoryService;


	@Autowired
	/*执行管理、包括启动、推进、删除流程实例等操作*/
	private RuntimeService runtimeService;


	@Autowired
	/*任务管理,可以做任务的查询的*/
	private TaskService taskService;


}
